using System;
using System.Collections.Generic;
using System.Collections.Specialized;

namespace PSSymbolStore.Manager
{
    public delegate void ReportProgressDelegate(int progressPercentage);

    public class TransactionManagerPresenter : IDisposable
    {
        private readonly ITransactionManagerView _view;
        private readonly TransactionManagerHost _host;
        private readonly TransactionManagerHostUserInterface _hostUI;
        private readonly ISymStoreTask _symStoreTask;
        private SortableBindingList<AddTransaction> _transactions;

        private string _symbolStoreLocation = String.Empty;
        private StringCollection _mru;

        public TransactionManagerPresenter(ITransactionManagerView view)
        {
            _view = view;
            _view.SaveSettings += OnViewSaveSettings;

            _hostUI = new TransactionManagerHostUserInterface(_view);
            _host = new TransactionManagerHost(_hostUI);
            _symStoreTask = new SymStoreTask(_host);

            Properties.Settings.Default.PropertyChanged += OnSettingChanged;
        }

        static void OnViewSaveSettings(object sender, EventArgs e)
        {
            Properties.Settings.Default.Save();
        }

        #region IDisposable Members

        public void Dispose()
        {
            _view.SaveSettings -= OnViewSaveSettings;
            Properties.Settings.Default.PropertyChanged -= OnSettingChanged;
        }

        #endregion

        #region Public Methods

        public string SymbolStoreLocation
        {
            get { return _symbolStoreLocation; }
            set
            {
                if (!_symbolStoreLocation.Equals(value, StringComparison.CurrentCultureIgnoreCase))
                {
                    _symbolStoreLocation = (value != null) ? value.TrimEnd('\\') : String.Empty;

                    Open();
                }
            }
        }

        public void Initialize()
        {
            // Load the MRU
            UpdateViewMruList();
            
            // Open the default symbol store location
            if (!String.IsNullOrEmpty(Properties.Settings.Default.SymbolServerLocation))
            {
                SymbolStoreLocation = Properties.Settings.Default.SymbolServerLocation;
            }
        }

        public void Refresh()
        {
            // Parse and load the entries
            _transactions = _symStoreTask.GetTransactions();
            // Update the view's data source
            _view.Transactions = _transactions;
        }

        public void Delete(AddTransactionList transactions)
        {
            if (transactions == null) throw new ArgumentNullException("transactions");

            _view.ClearOutput();

            _symStoreTask.Delete(transactions);

            Refresh();
        }

        public void Lock(AddTransactionList transactions)
        {
            if (transactions == null) throw new ArgumentNullException("transactions");
            if (transactions.Count == 0) return;

            _view.ClearOutput();

            _symStoreTask.Lock(transactions);

            Refresh();
        }

        public void Unlock(AddTransactionList transactions)
        {
            if (transactions == null) throw new ArgumentNullException("transactions");
            if (transactions.Count == 0) return;

            _view.ClearOutput();

            _symStoreTask.Unlock(transactions);

            Refresh();
        }

        #endregion Public Methods

        #region Private Methods

        private void Open()
        {
            _symStoreTask.SymbolStoreLocation = SymbolStoreLocation;

            // Parse and load the entries
            _transactions = _symStoreTask.GetTransactions();

            // Save the last opened location
            Properties.Settings.Default.SymbolServerLocation = SymbolStoreLocation;

            _view.SymbolStoreLocation = SymbolStoreLocation;

            AddToMru(SymbolStoreLocation);

            // Update the view's data source
            _view.Transactions = _transactions;
            _view.ClearOutput();
        }

        private void UpdateViewMruList()
        {
            _view.SymbolStoreMRU = GetMRUList();
        }

        private void OnSettingChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (String.Compare(e.PropertyName, "SymbolServerMRUList", true) == 0)
            {
                UpdateViewMruList();
            }
        }

        private IList<string> GetMRUList()
        {
            var mruList = new List<string>();

            _mru = Properties.Settings.Default.SymbolServerMRUList ?? new StringCollection();

            if (_mru.Count > 0)
            {
                foreach (string mruString in _mru)
                {
                    // If the MRU has a pipe it's a "legacy" MRU item
                    // just use the 1st portion of the string
                    if (mruString.Contains("|"))
                    {
                        string[] oldMru = mruString.Split('|');
                        if ((oldMru.Length > 0) && !String.IsNullOrEmpty(oldMru[0]))
                        {
                            mruList.Add(oldMru[0]);
                        }
                    }
                    else
                    {
                        mruList.Add(mruString);
                    }
                }
            }

            return mruList;
        }

        private void AddToMru(string item)
        {
            if (String.IsNullOrEmpty(item))
            {
                return;
            }

            if (_mru == null)
            {
                _mru = new StringCollection();
            }

            // Verify that the item doesn't exist already
            foreach (string mru in _mru)
            {
                if (String.Compare(mru, item, true) == 0)
                {
                    // Found, do nothing.
                    return;
                }
            }

            // We'll only save the last 5
            if (_mru.Count == 5)
            {
                // Remove the last one
                _mru.RemoveAt(4);
            }

            // Add the new one to the top
            _mru.Insert(0, item);

            Properties.Settings.Default.SymbolServerMRUList = _mru;
        }

        #endregion Private Methods
    }
}
